import { Spinner, SpinnerSize, Switch, Button, MenuItem } from '@blueprintjs/core';
import { Select } from '@blueprintjs/select';
import { useState, useEffect } from 'react';

import { GetRespLists, RemoveRespList, ToggleReplList } from '../../wailsjs/go/cfg/Config';
// eslint-disable-next-line import/order
import { type cfg } from '../../wailsjs/go/models';
import './index.css';
import { AppToaster } from '../common/toaster';

import { CreateRespList } from './CreateRespList';
import { RespListType } from './types';

export function RespLists() {
  const [state, setState] = useState<{
    respLists: cfg.Resp[];
    loading: boolean;
  }>({
    respLists: [],
    loading: true,
  });

  const fetchRespLists = async () => {
    const respLists = await GetRespLists();
    setState({ ...state, respLists, loading: false });
  };

  useEffect(() => {
    (async () => {
      await fetchRespLists();
    })();
  }, []);

  const [type, setType] = useState<RespListType>(RespListType.GENERAL);
  return (
    <>
      <Select
        items={Object.values(RespListType)}
        itemRenderer={(item) => (
          <MenuItem
            key={item}
            text={
              <>
                {item[0].toUpperCase() + item.slice(1)}
                <span className="bp5-text-muted filter-lists__select-count">
                  ({state.respLists.filter((respList) => respList.type === item).length}/
                  {state.respLists.filter((respList) => respList.type === item).length})
                </span>
              </>
            }
            onClick={() => {
              setType(item);
            }}
            active={item === type}
          />
        )}
        onItemSelect={(item) => {
          setType(item);
        }}
        popoverProps={{ minimal: true, matchTargetWidth: true }}
        filterable={false}
      >
        <Button text={type[0].toUpperCase() + type.slice(1)} rightIcon="caret-down" />
      </Select>

      {state.loading && <Spinner size={SpinnerSize.SMALL} className="filter-lists__spinner" />}

      {state.respLists
        .filter((respList) => respList.type === type)
        .map((respList) => (
          // eslint-disable-next-line no-self-compare
          <ListItem key={respList.host} respList={respList} showDelete={1 === 1} onChange={fetchRespLists} />
        ))}

      <CreateRespList onAdd={fetchRespLists} />
      {/* {type === RespListType.GENERAL && <CreateRespList onAdd={fetchRespLists} />} */}
    </>
  );
}

function ListItem({
  respList,
  showDelete,
  onChange,
}: {
  respList: cfg.Resp;
  showDelete?: boolean;
  onChange?: () => void;
}) {
  const [switchLoading, setSwitchLoading] = useState(false);
  const [deleteLoading, setDeleteLoading] = useState(false);
  return (
    <div className="filter-lists__list">
      <div className="filter-lists__list-header">
        <h3 className="filter-lists__list-name">{respList.name}</h3>
        <Switch
          checked={respList.enabled}
          disabled={switchLoading}
          onChange={async (e) => {
            setSwitchLoading(true);
            const err = await ToggleReplList(respList.host, e.currentTarget.checked);
            if (err) {
              AppToaster.show({
                message: `Failed to toggle filter list: ${err}`,
                intent: 'danger',
              });
            }
            setSwitchLoading(false);
            onChange?.();
          }}
          large
          className="filter-lists__list-switch"
        />
      </div>
      <div className="bp5-text-muted filter-lists__list-url">{respList.host}</div>

      {showDelete && (
        <Button
          icon="trash"
          intent="danger"
          small
          className="filter-lists__list-delete"
          loading={deleteLoading}
          onClick={async () => {
            setDeleteLoading(true);
            const err = await RemoveRespList(respList.host);
            if (err) {
              AppToaster.show({
                message: `Failed to remove filter list: ${err}`,
                intent: 'danger',
              });
            }
            setDeleteLoading(false);
            onChange?.();
          }}
        >
          Delete
        </Button>
      )}
    </div>
  );
}
